﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Media;
using ScrumTable.BL.DM.DataManagement;
using ScrumTable.Common.Collections;
using ScrumTable.Common.FileSystem;
using ScrumTable.Common.Threading;
using ScrumTable.Common.Unity;
using ScrumTable.UI.ViewModel.Data;

#endregion

namespace ScrumTable.UI.ViewModel
{
    /// <summary>
    /// Attachment for the View model
    /// </summary>
    public class AttachmentViewModel : ViewModelBase, IViewModelData<Attachment>
    {

        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------
        /// <summary>
        /// The attachment from the BL.
        /// </summary>
        private readonly Attachment _attachment;
        private bool _isSaved = true;
 
        
        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------
        private static readonly List<string>  PngAttachments = new List<string> { ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".img", ".tiff", ".tif" };
    
        /// <summary>
        /// Gets the original attachment from the BL.
        /// </summary>
        /// <value></value>
        public Attachment Original { get { return _attachment; } }


        public bool IsImage
        {
            get { return PngAttachments.Contains(Original.Extension); }
        }

        public bool IsSaved
        {
            get { return _isSaved; }
            set { _isSaved = value; SendPropertyChanged("IsSaved"); }
        }


     
        /// <summary>
        /// Gets the id of the attachment.
        /// </summary>
        public string Id
        {
            get { return _attachment.Id; }
        }

        /// <summary>
        /// Gets the name of the attachment.
        /// </summary>
        public string Name
        {
            get { return _attachment.Name; }
            set
            {
                if (value.Length == 0)
                {
                    throw new Exception();
                }
                _attachment.Name = value;
                SendPropertyChanged("Name");
                Save();
            }
        }

        /// <summary>
        /// Gets the parent of the attachment
        /// </summary>
        public DomainBase Parent
        {
            get
            {
                return _attachment.Parent;
            }
        }
        
        /// <summary>
        /// Gets the path to the attachement
        /// </summary>
        public Uri Uri
        {
            get
            {
                return Original.Uri;
            }
            set
            {
                Original.Uri = value;
                SendPropertyChanged("Uri");
                Save();
            }
        }


   

        /// <summary>
        /// Gets the attachment description text.
        /// </summary>
        public string Description
        {
            get { return _attachment.Description; }
            set
            {
                _attachment.Description = value;
                SendPropertyChanged("Description");
                Save();
            }
        }




        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="BugViewModel"/> class.
        /// </summary>
        /// <param name="attachment">The attachment.</param>
        public AttachmentViewModel(Attachment attachment)
        {
            _attachment = attachment;
            _attachment.PropertyChanged += OnAttachmentPropertyChanged;
        }
        
        /// <summary>
        /// Releases managed (c# or .net) resources.
        /// </summary>
        protected override void ReleaseManagedResources()
        {
            _attachment.PropertyChanged -= OnAttachmentPropertyChanged;
            base.ReleaseManagedResources();
        }

        #endregion

        #region Overrides

        /// <summary>
        /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
        /// <returns>
        /// 	<c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        /// <exception cref="T:System.NullReferenceException">
        /// The <paramref name="obj"/> parameter is null.
        /// </exception>
        public override bool Equals(object obj)
        {
            if (obj is AttachmentViewModel) return Equals(obj as AttachmentViewModel);
            if (obj is Attachment) return Original.Equals(obj);

            return false;
        }

        /// <summary>
        /// Equalses the specified other.
        /// </summary>
        /// <param name="other">The other.</param>
        /// <returns></returns>
        public bool Equals(AttachmentViewModel other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return other.Id == Id; 
        }

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        public override int GetHashCode()
        {
            return (_attachment != null ? _attachment.GetHashCode() : 0);
        }

        #endregion

        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        /// <summary>
        /// Saves this instance.
        /// </summary>
        public void Save()
        {
            Original.Save();
        }

        public void OpenInExternalProgramm(Action downloaded)
        {
            string filePathRel;
            string filePathAbs;
            FileProcessor.GetFilePathAbsAndRel(out filePathRel, out filePathAbs, Original.Extension);

            new FileProcessor(Original.Context.ConnectionInformation.NetworkCredentials,
                            AppContainer.Resolve<IDataSyncDispatcher>(), Uri, filePathAbs,
                            downloaded,
                            (hasChanged) =>
                            {
                                if (hasChanged)
                                {
                                    var name = Name;
                                    Uri = new Uri(filePathAbs);
                                    Name = name;
                                }
                            });
        }
        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------


        void OnAttachmentPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            SendPropertyChanged(e.PropertyName);
        }
        
        #endregion
    }
}